package tfts

import (
	"fmt"
	"os"
)

type Event int

const (
	Noop        Event = iota
	TimeGoE           // 每秒触发一次
	DamagedE          // 承受伤害
	AttackE           // 每次攻击触发
	BeforeCastE       // 每次施法前触发
	AfterCastE        // 每次施法后触发
	ShieldE           // 获得护盾
	HealedE           // 获得治疗
)

const (
	Local  = 2 << 11
	bound_ = 2<<11 - 1
	TRACE  = 2 << 6
	ACTION = 2 << 5
	METRIC = 2 << 4
	NULL   = 0
)

var outputLevel = 6
var fd *os.File = nil

type attributeI interface {
	validI
	stat() *attrMeta
}

type validI interface {
	valid() bool
}

type handlerI interface {
	handle(Event)
}

func Level(level int) {
	outputLevel = level
}

func openFd(name string) {
	dir := `trace`
	if _, err := os.Stat(dir); os.IsNotExist(err) {
		// 创建子目录，包括所有必要的父目录
		err = os.Mkdir(dir, os.ModePerm)
		if err != nil {
			fmt.Println("Error creating directory:", err)
			return
		}
	} else if err != nil {
		panic(err)
	}
	for i := 0; i < 30; i++ {
		if _, err := os.Stat(fmt.Sprintf("%s\\%s_%d.txt", dir, name, i)); os.IsNotExist(err) {
			file, err := os.OpenFile(fmt.Sprintf("%s\\%s_%d.txt", dir, name, i), os.O_CREATE|os.O_WRONLY, 0644)
			if err != nil {
				panic(err)
			}
			fd = file
			break
		}
	}
}

func closeFdIfNeed() {
	if fd != nil {
		fd.Close()
	}
}

func traceLog(fmtStr string, v ...any) {
	if outputLevel&bound_ < TRACE {
		return
	}
	if outputLevel&Local == Local {
		fd.WriteString(fmt.Sprintf(fmtStr, v...))
	} else {
		fmt.Printf(fmtStr, v...)
	}
}

func actionLog(fmtStr string, v ...any) {
	if outputLevel&bound_ < ACTION {
		return
	}
	if outputLevel&Local == Local {
		fd.WriteString(fmt.Sprintf(fmtStr, v...))
	} else {
		fmt.Printf(fmtStr, v...)
	}
}

func metricLog(fmtStr string, v ...any) {
	if outputLevel&bound_ < METRIC {
		return
	}
	if outputLevel&Local == Local {
		fd.WriteString(fmt.Sprintf(fmtStr, v...))
	} else {
		fmt.Printf(fmtStr, v...)
	}
}

func (e Event) String() string {
	switch e {
	case TimeGoE:
		return "Time"
	case AttackE:
		return "Attack"
	case BeforeCastE:
		return "Cast"
	case AfterCastE:
		return "Cast"
	default:
		panic("unknown hook flag")
	}
}
